home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
3dkit1.zip
/
3DVTO2D.C
< prev
next >
Wrap
Text File
|
1992-05-25
|
5KB
|
177 lines
/* 3DVto2D.c - convert 3DV data to 2-D list format */
/* Oscar Garcia <garciao@mof.govt.nz>, May 1992 */
/* uses getopt */
int getopt(int argc, char *argv[], char *options);
extern int optind;
extern char *optarg;
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define USAGE "usage: 3DVto2D [/tx] [/nx] [/dx] [input_file [output_file]]\n\
\tIf file names are omitted, the standard i/o streams are used.\n\
\tOptions (with defaults):\n\
\t\t/t0 - Latitude, degrees\n\
\t\t/n0 - Longitude, degrees\n\
\t\t/d-3 - Viewing distance. Zero gives orthogonal projection.\n\
\t\t Positive is in user units to object center.\n\
\t\t Negative is relative to object size.\n\
\t\t Default -3 is as in 3dv."
#define ERROR(msg) {fputs(msg,stderr),exit(1);}
#define PERROR(msg) {perror(msg),exit(1);}
#define BIG 3e33
#define EPS 1e-9
#define RADIANS 3.141592/180
#define DDEFAULT -3
void main(int argc, char* argv[])
{
int i, j, n;
double scale, slon, clon, slat, clat, t[3][3],
lat = 0, lon = 0, dist = DDEFAULT;
char options[] = "t:n:d:";
FILE *infile = stdin, *outfile = stdout;
typedef double POINT[3];
POINT min, max, centre, xx, *x;
/* get options */
while ((n = getopt(argc, argv, options)) != EOF)
if (n == '?')
ERROR(USAGE)
else
switch (n)
{ case 't': lat = atof(optarg); break;
case 'n': lon = atof(optarg); break;
case 'd': dist = atof(optarg); break;
}
/* open files */
if (optind < argc - 2)
ERROR(USAGE); /* too many */
if (optind < argc)
{ infile = fopen(argv[optind], "rt");
if (infile == NULL)
ERROR("Can't open input file");
if (++optind < argc)
{ outfile = fopen(argv[optind], "wt");
if (outfile == NULL)
ERROR("Can't open output file");
}
}
/* read points */
i = fscanf(infile, "%d", &n);
if (i != 1 || ferror(infile))
PERROR("Bad input file");
#ifdef __MSDOS__
if ((unsigned)n * sizeof(POINT) > 0xfff0U)
ERROR("64k memory block limit exceeded");
#endif
x = malloc((unsigned)n * sizeof(POINT));
if (x == NULL)
ERROR("Out of memory");
for (j = 0; j < 3; j++)
{ min[j] = BIG;
max[j] = -BIG;
}
for (i = 0; i < n; i++)
{ fscanf(infile, "%lf %lf %lf", &x[i][0], &x[i][1], &x[i][2]);
for (j = 0; j < 3; j++)
{ if (x[i][j] < min[j])
min[j] = x[i][j];
else if (x[i][j] > max[j])
max[j] = x[i][j];
}
}
if (ferror(infile))
PERROR("Error reading input");
/* get centre and distance */
for (j = 0, scale = 0.0; j < 3; j++)
{ centre[j] = (min[j] + max[j]) / 2;
scale = scale + (max[j] - min[j]) * (max[j] - min[j]);
}
if (dist < -EPS) /* perspective, relative dist; convert to absolute */
dist *= sqrt(scale * (1 + 0.25 / (dist * dist))) / -0.99;
/* transformation matrix */
slon = sin(lon * RADIANS);
clon = cos(lon * RADIANS);
slat = sin(lat * RADIANS);
clat = cos(lat * RADIANS);
t[0][0] = clon;
t[0][1] = - slon;
t[1][0] = clat * slon;
t[1][1] = clat * clon;
t[1][2] = slat;
t[2][0] = - slat * slon;
t[2][1] = - slat * clon;
t[2][2] = clat;
/* rotate and project along y */
min[0] = min[2] = BIG; /* 2-d coords will be saved in 0 and 2 */
max[0] = max[2] = -BIG;
for (i = 0; i < n; i++)
{ for (j = 0; j < 3; j++)
xx[j] = x[i][j] - centre[j];
x[i][0] = t[0][0] * xx[0] + t[0][1] * xx[1];
x[i][1] = t[1][0] * xx[0] + t[1][1] * xx[1] + t[1][2] * xx[2];
x[i][2] = t[2][0] * xx[0] + t[2][1] * xx[1] + t[2][2] * xx[2];
if (dist > EPS) /* perspective */
{ x[i][0] /= 1 - x[i][1] / dist;
x[i][2] /= 1 - x[i][1] / dist;
} /* x[i][1] not used again here, but might need it some day */
if (x[i][0] < min[0])
min[0] = x[i][0];
else if (x[i][0] > max[0])
max[0] = x[i][0];
if (x[i][2] < min[2])
min[2] = x[i][2];
else if (x[i][2] > max[2])
max[2] = x[i][2];
}
/* factor for scaling to [-1, 1] */
scale = max[0];
if (-min[0] > scale)
scale = -min[0];
if (max[2] > scale)
scale = max[2];
if (-min[2] > scale)
scale = -min[2];
scale = 1 / scale;
/* output info */
fscanf(infile, "%d", &n);
fprintf(outfile, "# n=%d scale=%g x_range=[%g:%g] y_range=[%g:%g]\n",
n, 1/scale, scale*min[0], scale*max[0], scale*min[2], scale*max[2]);
fprintf(outfile, "# latitude=%g longitude=%g distance=%g\n",
lat, lon, dist);
/* output data */
while (n-- > 0)
{ fscanf(infile, "%d %d", &i, &j);
if (j == 0)
putc('\n', outfile); /* blank line (move) */
fprintf(outfile, "%g %g %d\n",
scale * x[i-1][0], scale * x[i-1][2], j);
}
if (ferror(infile))
PERROR("Error reading input");
if (feof(infile))
ERROR("Unexpected end of file on input");
fclose(infile);
if (ferror(outfile))
PERROR("Error during output");
fclose(outfile);
}